/*
Copyright 2024 - 2025 Zen HuiFer

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"igp/docs"
	"igp/glob"
	"igp/initialize"
	"igp/router"
	"igp/servlet"
	"igp/task"
	"net/http"
	_ "net/http/pprof"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	swaggerfiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
	"go.uber.org/zap"
)

// Beat
// 健康检查
// @Summary      健康检查
// @Tags         beat
// @Produce      json
// @Success      20000  {object}  string
// @Router       /beat [get]
func Beat(g *gin.Context) {
	result := servlet.JSONResult{}
	result.Message = "操作成功"
	result.Code = 20000
	result.Data = "beat"
	g.JSON(http.StatusOK, result)

}

// @title Go语言物联网
// @version 1.0
// @description 基于Go语言的物联网项目

// @contact.name Zen Huifer
// @contact.url https://github.com/huifer
// @contact.email huifer97@163.com

// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html

// @host http://127.0.0.1:8080/
// @BasePath /
func main() {

	gin.SetMode(gin.ReleaseMode)
	r := gin.New()
	group := r.Group("/")
	group.Use(CORSMiddleware())
	group.Use(ExceptionMiddleware)
	r.Use(func(c *gin.Context) {
		clientIP := c.ClientIP() // 获取客户端 IP
		zap.S().Info("Request from IP: %s", clientIP)
		c.Next() // 继续处理下一个中间件或请求
	})

	r.Use(CORSMiddleware())
	r.Use(ExceptionMiddleware)
	r.POST("/login", router.Login)

	initialize.InitAll(group)
	task.InitTask()

	docs.SwaggerInfo.BasePath = "/"
	r.GET("/metrics", gin.WrapH(promhttp.Handler()))
	r.GET("/beat", Beat)
	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
	err := r.Run(":" + strconv.Itoa(glob.GConfig.NodeInfo.Port))
	if err != nil {
		zap.S().Fatal("启动服务失败", zap.Error(err))
	}

}

func CORSMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {

		c.Header("Access-Control-Allow-Origin", "*")
		c.Header("Access-Control-Allow-Credentials", "true")
		c.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
		c.Header("Access-Control-Allow-Methods", "POST,HEAD,PATCH, OPTIONS, GET, PUT")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}

		c.Next()
	}
}

func ExceptionMiddleware(c *gin.Context) {
	defer func() {
		if err := recover(); err != nil {
			// 简单返回友好提示，具体可自定义发生错误后处理逻辑
			glob.GLog.Sugar().Error(err)

			servlet.Error(c, err)
			c.Abort()
		}
	}()
	c.Next()
}
